
#ifndef _HASH_H
#  define _HASH_H

typedef struct _hash_key {

  unsigned int hash;
  void *key;
  unsigned int length;

} hash_key;

typedef struct _hash_elem {

  hash_key *key;
  void *data;
  char used;

} hash_elem;

typedef struct _hash_t {

  unsigned int space;
  unsigned int entries;

  hash_elem *table;

} hash_t;

typedef struct _hash_iterator {

  hash_t *table;
  unsigned int offset;

} hash_iterator;

#  ifndef LOAD_FACT
#    define LOAD_FACT .65
#  endif
#  ifndef LOAD_INCREASE
#    define LOAD_INCREASE 1.5
#  endif

hash_t        *hash_new(unsigned int);
hash_key      *hash_new_key(void *, unsigned int);
hash_elem     *hash_new_elem(hash_key *, void *);
hash_t        *hash_add(hash_t *, void *, unsigned int, void *);
hash_t        *hash_add_elem(hash_t *, hash_elem *);
hash_elem     *hash_get(hash_t *, void *, unsigned int);
hash_elem     *hash_get_elem(hash_t *, hash_key *);
hash_elem     *hash_remove(hash_t *, void *, unsigned int);
hash_elem     *hash_remove_key(hash_t *, hash_key *);
hash_iterator *hash_new_iterator(hash_t *);
hash_elem     *hash_iterate(hash_iterator *);
void           hash_print(hash_t *);
void           hash_print_key(hash_key *);
void           hash_print_elem(hash_elem *);

#endif
